import GameConfig from '../config/GameConfig.js';
import Snake from './Snake.js';
import Food from './Food.js';
import ScorePanel from '../ui/ScorePanel.js';
import GameMenu from '../ui/GameMenu.js';
import GameOver from '../ui/GameOver.js';
import SoundManager from '../utils/SoundManager.js';
/**
 * 游戏主类
 */
export default class Game {
    /**
     * 初始化游戏
     * @param {HTMLCanvasElement} canvas - 游戏画布
     */
    constructor(canvas) {
        this.canvas = canvas;
        this.ctx = canvas.getContext('2d');
        this.state = GameConfig.STATES.LOADING;
        
        this.snake = new Snake();
        this.food = new Food(this);
        this.scorePanel = new ScorePanel(this.ctx);
        this.menu = new GameMenu(this.ctx);
        this.gameOver = new GameOver(this.ctx);
        
        this.lastUpdateTime = 0;
        this.images = {};
        
        this.loadImages();
        this.initSound();
        this.bindEvents();
    }

    /**
     * 加载图片资源
     */
    async loadImages() {
        const loadingScreen = document.getElementById('loadingScreen');
        const loadingText = loadingScreen?.querySelector('.loading-text');
        
        const images = {
            SNAKE_HEAD: '/images/snake-head.png',
            SNAKE_BODY: '/images/snake-body.png',
            FOOD: '/images/food.png'
        };
    
        const totalImages = Object.keys(images).length;
        let loadedCount = 0;
    
        try {
            const promises = Object.entries(images).map(([key, src]) => {
                return new Promise((resolve, reject) => {
                    const img = new Image();
                    img.onload = () => {
                        loadedCount++;
                        if (loadingText) {
                            loadingText.textContent = `加载中... ${Math.floor((loadedCount/totalImages) * 100)}%`;
                        }
                        resolve([key, img]);
                    };
                    img.onerror = () => reject(new Error(`Failed to load image: ${src}`));
                    img.src = src;
                });
            });
    
            const loadedImages = await Promise.all(promises);
            loadedImages.forEach(([key, img]) => {
                this.images[key] = img;
            });
    
            // 所有图片加载完成后，添加淡出动画
            if (loadingScreen) {
                loadingScreen.style.transition = 'opacity 0.5s';
                loadingScreen.style.opacity = '0';
                setTimeout(() => {
                    loadingScreen.style.display = 'none';
                }, 500);
            }
    
            this.state = GameConfig.STATES.MENU;
            
        } catch (error) {
            console.error('Error loading images:', error);
            if (loadingText) {
                loadingText.textContent = '资源加载失败，请刷新重试';
                loadingText.style.color = '#ff6b6b';
            }
        }
    }

    /**
     * 初始化音效
     */
    async initSound() {
        await SoundManager.preload();
        const soundBtn = document.createElement('button');
        soundBtn.className = 'sound-btn';
        soundBtn.innerHTML = '🔊';
        soundBtn.onclick = () => {
            SoundManager.toggleMute();
            soundBtn.innerHTML = SoundManager.muted ? '🔇' : '🔊';
        };
        document.body.appendChild(soundBtn);
    }

    /**
     * 绑定事件处理
     */
    bindEvents() {
      document.addEventListener('keydown', (e) => {
          this.handleKeyPress(e);
      });

      this.canvas.addEventListener('click', (e) => {
          this.handleClick(e);
      });
  }

  /**
 * 处理键盘事件
 * @param {KeyboardEvent} e - 键盘事件
 */
handleKeyPress(e) {
  // 修改这里的事件处理逻辑
  if (e.key === 'Escape') {
      if (this.state === GameConfig.STATES.PLAYING) {
          this.state = GameConfig.STATES.PAUSED;
          console.log('Game paused'); // 调试用
      } else if (this.state === GameConfig.STATES.PAUSED) {
          this.state = GameConfig.STATES.PLAYING;
          console.log('Game resumed'); // 调试用
      }
      return;
  }

  // 只在游戏进行时处理方向键
  if (this.state === GameConfig.STATES.PLAYING) {
      switch(e.key) {
          case 'ArrowUp':
          case 'w':
              this.snake.setDirection('up');
              break;
          case 'ArrowDown':
          case 's':
              this.snake.setDirection('down');
              break;
          case 'ArrowLeft':
          case 'a':
              this.snake.setDirection('left');
              break;
          case 'ArrowRight':
          case 'd':
              this.snake.setDirection('right');
              break;
      }
  }
}
  /**
   * 处理点击事件
   * @param {MouseEvent} e - 鼠标事件
   */
  handleClick(e) {
      const rect = this.canvas.getBoundingClientRect();
      const x = e.clientX - rect.left;
      const y = e.clientY - rect.top;

      switch(this.state) {
          case GameConfig.STATES.MENU:
              if (this.menu.isStartButtonClicked(x, y)) {
                  this.startGame();
              } else if (this.menu.isSettingsButtonClicked(x, y)) {
                this.menu.showSettings();
            } 
              break;
          case GameConfig.STATES.GAME_OVER:
              this.state = GameConfig.STATES.MENU;
              SoundManager.loop('bgm');
              break;
      }
  }

  /**
   * 开始游戏
   */
  startGame() {
      this.snake.reset();
      this.food.regenerate();
      this.scorePanel.reset();
      this.state = GameConfig.STATES.PLAYING;

  }

  /**
   * 更新游戏状态
   */
  update() {
    if (this.state !== GameConfig.STATES.PLAYING) return;

    this.snake.update();
    const head = this.snake.move();

    // 检查是否吃到食物
    if (head.x === this.food.position.x && head.y === this.food.position.y) {
        SoundManager.play('eat');  // 添加吃食物音效
        this.snake.grow();
        this.food.regenerate();
        this.scorePanel.addScore(10);
    }

    // 获取游戏区域尺寸并检查碰撞
    const gameDimensions = this.getGameAreaDimensions();
    if (this.snake.checkCollision(gameDimensions)) {
        this.state = GameConfig.STATES.GAME_OVER;
        this.scorePanel.saveHighScore();
        SoundManager.play('die');     // 添加死亡音效
        SoundManager.stop('bgm');     // 停止背景音乐
    }
  }

  /**
   * 绘制游戏
   */
  draw() {
      // 清空画布
      this.ctx.fillStyle = GameConfig.COLORS.BACKGROUND;
      this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);

      switch(this.state) {
          case GameConfig.STATES.MENU:
              this.menu.draw();
              break;
          case GameConfig.STATES.PLAYING:
          case GameConfig.STATES.PAUSED:
              this.drawGame();
              if (this.state === GameConfig.STATES.PAUSED) {
                  this.drawPaused();
              }
              break;
          case GameConfig.STATES.GAME_OVER:
              this.drawGame();
              this.gameOver.draw(this.scorePanel.score);
              break;
      }
  }

  /**
   * 绘制游戏画面
   */
  drawGame() {
    // 首先绘制游戏区域边框
    this.drawGameArea();
    
    // 然后绘制网格
    this.drawGrid();
    
    // 绘制蛇和食物
    this.drawSnake();
    this.drawFood();
    
    // 最后绘制分数面板（确保它在最上层）
    this.scorePanel.draw();
}

    /**
   * 绘制游戏区域边框
   */
  drawGameArea() {
    const { GAME_AREA } = GameConfig.LAYOUT;
    
    // 使用配置中的边距
    const topMargin = GAME_AREA.TOP_MARGIN;
    const padding = GAME_AREA.PADDING;
    
    // 绘制边框
    this.ctx.strokeStyle = '#333';
    this.ctx.lineWidth = 2;
    this.ctx.strokeRect(
        padding, 
        topMargin, 
        this.canvas.width - padding * 2, 
        this.canvas.height - topMargin - padding
    );

    // 可选的背景
    this.ctx.fillStyle = 'rgba(255, 255, 255, 0.02)';
    this.ctx.fillRect(
        padding, 
        topMargin, 
        this.canvas.width - padding * 2, 
        this.canvas.height - topMargin - padding
    );
  }

  /**
   * 绘制网格
   */
  drawGrid() {
    const { GAME_AREA } = GameConfig.LAYOUT;
    const topMargin = GAME_AREA.TOP_MARGIN;
    const padding = GAME_AREA.PADDING;
    
    this.ctx.strokeStyle = GameConfig.COLORS.GRID;
    this.ctx.lineWidth = 0.5;

    // 绘制垂直线
    for (let x = padding; x <= this.canvas.width - padding; x += GameConfig.GRID_SIZE) {
        this.ctx.beginPath();
        this.ctx.moveTo(x, topMargin);
        this.ctx.lineTo(x, this.canvas.height - padding);
        this.ctx.stroke();
    }

    // 绘制水平线
    for (let y = topMargin; y <= this.canvas.height - padding; y += GameConfig.GRID_SIZE) {
        this.ctx.beginPath();
        this.ctx.moveTo(padding, y);
        this.ctx.lineTo(this.canvas.width - padding, y);
        this.ctx.stroke();
    }
  }

/**
 * 绘制蛇
 */
drawSnake() {
  this.snake.segments.forEach((segment, index) => {
    const pos = this.gameToCanvasPosition(segment.x, segment.y);
    
    if (this.images.SNAKE_HEAD && this.images.SNAKE_BODY) {
        // 使用图片绘制
        const image = index === 0 ? this.images.SNAKE_HEAD : this.images.SNAKE_BODY;
        this.ctx.save();
        this.ctx.translate(
            pos.x + GameConfig.GRID_SIZE/2, 
            pos.y + GameConfig.GRID_SIZE/2
        );
        
        if (index === 0) {
            let rotation = 0;
            switch(this.snake.direction) {
                case 'up': rotation = -Math.PI/2; break;
                case 'down': rotation = Math.PI/2; break;
                case 'left': rotation = Math.PI; break;
                case 'right': rotation = 0; break;
            }
            this.ctx.rotate(rotation);
        }
        
        this.ctx.drawImage(
            image,
            -GameConfig.GRID_SIZE/2,
            -GameConfig.GRID_SIZE/2,
            GameConfig.GRID_SIZE,
            GameConfig.GRID_SIZE
        );
        this.ctx.restore();
    } else {
        // 使用简单图形绘制
        this.ctx.fillStyle = index === 0 ? 
            GameConfig.COLORS.SNAKE_HEAD : 
            GameConfig.COLORS.SNAKE_BODY;
        
        this.ctx.beginPath();
        Canvas.roundRect(
            this.ctx,
            pos.x, 
            pos.y, 
            GameConfig.GRID_SIZE - 1, 
            GameConfig.GRID_SIZE - 1,
            index === 0 ? 4 : 2
        );
        this.ctx.fill();
    }
});
}

/**
* 绘制食物
*/
drawFood() {
  const pos = this.gameToCanvasPosition(this.food.position.x, this.food.position.y);
    
  if (this.images.FOOD) {
      this.ctx.drawImage(
          this.images.FOOD,
          pos.x,
          pos.y,
          GameConfig.GRID_SIZE,
          GameConfig.GRID_SIZE
      );
  } else {
      this.ctx.fillStyle = GameConfig.COLORS.FOOD;
      this.ctx.beginPath();
      this.ctx.arc(
          pos.x + GameConfig.GRID_SIZE/2,
          pos.y + GameConfig.GRID_SIZE/2,
          GameConfig.GRID_SIZE/2 - 1,
          0,
          Math.PI * 2
      );
      this.ctx.fill();
  }
}

/**
 * 绘制暂停画面
 */
drawPaused() {
  this.ctx.save();
    
    // 添加半透明黑色遮罩，使用渐变效果
    const gradient = this.ctx.createLinearGradient(0, 0, 0, this.canvas.height);
    gradient.addColorStop(0, 'rgba(0, 0, 0, 0.7)');
    gradient.addColorStop(0.5, 'rgba(0, 0, 0, 0.85)');
    gradient.addColorStop(1, 'rgba(0, 0, 0, 0.7)');
    this.ctx.fillStyle = gradient;
    this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);

    // 绘制暂停图标
    this.drawPauseIcon();

    // 绘制暂停标题
    this.ctx.textAlign = 'center';
    this.ctx.textBaseline = 'middle';
    
    // 主标题
    this.ctx.font = 'bold 48px "Microsoft YaHei"';
    
    // 创建文字渐变
    const textGradient = this.ctx.createLinearGradient(
        this.canvas.width/2 - 100,
        this.canvas.height/2 - 50,
        this.canvas.width/2 + 100,
        this.canvas.height/2 + 50
    );
    textGradient.addColorStop(0, '#4CAF50');
    textGradient.addColorStop(0.5, '#81C784');
    textGradient.addColorStop(1, '#4CAF50');
    
    this.ctx.fillStyle = textGradient;
    
    // 添加文字阴影
    this.ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
    this.ctx.shadowBlur = 15;
    this.ctx.shadowOffsetY = 4;
    
    this.ctx.fillText('游戏暂停', 
        this.canvas.width/2, 
        this.canvas.height/2 - 40
    );

    // 绘制提示文本
    this.ctx.shadowBlur = 10;
    this.ctx.shadowOffsetY = 2;
    this.ctx.font = '24px "Microsoft YaHei"';
    this.ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
    this.ctx.fillText('按 ESC 继续游戏', 
        this.canvas.width/2, 
        this.canvas.height/2 + 20
    );

    // 绘制控制提示
    this.drawControlsHelp();

    this.ctx.restore();
}

/**
 * 绘制暂停图标
 */
drawPauseIcon() {
  const centerX = this.canvas.width / 2;
  const iconY = this.canvas.height / 2 - 120;
  const size = 60;
  
  this.ctx.save();
  
  // 绘制圆形背景
  this.ctx.beginPath();
  this.ctx.arc(centerX, iconY, size/2, 0, Math.PI * 2);
  this.ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
  this.ctx.fill();

  // 绘制暂停条
  this.ctx.fillStyle = '#4CAF50';
  this.ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';
  this.ctx.shadowBlur = 8;
  this.ctx.shadowOffsetY = 2;

  // 左边暂停条
  this.ctx.fillRect(
      centerX - 15,
      iconY - 20,
      10,
      40
  );

  // 右边暂停条
  this.ctx.fillRect(
      centerX + 5,
      iconY - 20,
      10,
      40
  );

  this.ctx.restore();
}
/**
 * 绘制控制提示
 */
drawControlsHelp() {
  this.ctx.save();
    
    const startY = this.canvas.height/2 + 100;
    const lineHeight = 30;
    const centerX = this.canvas.width/2;
    
    this.ctx.font = '18px "Microsoft YaHei"';
    this.ctx.textBaseline = 'middle';
    
    const controls = [
        { key: '↑ W', desc: '向上移动' },
        { key: '↓ S', desc: '向下移动' },
        { key: '← A', desc: '向左移动' },
        { key: '→ D', desc: '向右移动' },
        { key: 'ESC', desc: '暂停/继续' }
    ];

    // 计算最长的按键和描述文本宽度
    let maxKeyWidth = 0;
    let maxDescWidth = 0;
    controls.forEach(control => {
        const keyWidth = this.ctx.measureText(control.key).width;
        const descWidth = this.ctx.measureText(control.desc).width;
        maxKeyWidth = Math.max(maxKeyWidth, keyWidth);
        maxDescWidth = Math.max(maxDescWidth, descWidth);
    });

    // 计算整个控制说明区域的总宽度
    const keyBoxPadding = 10; // 按键背景框的内边距
    const spacing = 20; // 按键和描述之间的间距
    const totalWidth = maxKeyWidth + (keyBoxPadding * 2) + spacing + maxDescWidth;
    
    controls.forEach((control, index) => {
        const y = startY + index * lineHeight;
        
        // 计算按键框的起始x坐标（居中）
        const keyBoxWidth = maxKeyWidth + (keyBoxPadding * 2);
        const startX = centerX - totalWidth/2;

        // 绘制按键背景
        this.ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
        this.roundRect(
            startX,
            y - 12,
            keyBoxWidth,
            24,
            5
        );
        this.ctx.fill();

        // 绘制按键文本（在按键框内居中）
        this.ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
        this.ctx.textAlign = 'center';
        this.ctx.fillText(
            control.key, 
            startX + keyBoxWidth/2,
            y
        );

        // 绘制描述文本
        this.ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';
        this.ctx.textAlign = 'left';
        this.ctx.fillText(
            control.desc, 
            startX + keyBoxWidth + spacing,
            y
        );
    });

    // 可选：添加标题
    const titleY = startY - 40;
    this.ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
    this.ctx.font = 'bold 20px "Microsoft YaHei"';
    this.ctx.textAlign = 'center';
    this.ctx.fillText('游戏控制', centerX, titleY);

    // 可选：添加装饰线
    this.ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
    this.ctx.lineWidth = 1;
    this.ctx.beginPath();
    this.ctx.moveTo(centerX - 100, titleY + 15);
    this.ctx.lineTo(centerX + 100, titleY + 15);
    this.ctx.stroke();

    this.ctx.restore();
}

/**
 * 绘制圆角矩形
 */
roundRect(x, y, width, height, radius) {
  this.ctx.beginPath();
  this.ctx.moveTo(x + radius, y);
  this.ctx.arcTo(x + width, y, x + width, y + height, radius);
  this.ctx.arcTo(x + width, y + height, x, y + height, radius);
  this.ctx.arcTo(x, y + height, x, y, radius);
  this.ctx.arcTo(x, y, x + width, y, radius);
  this.ctx.closePath();
}

/**
 * 游戏主循环
 * @param {number} timestamp - 时间戳
 */
gameLoop(timestamp) {
  const now = timestamp || performance.now();
  
  if (!this.lastUpdateTime) {
      this.lastUpdateTime = now;
  }

  // 清空画布
  this.ctx.fillStyle = GameConfig.COLORS.BACKGROUND;
  this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);

  switch (this.state) {
      case GameConfig.STATES.MENU:
          this.menu.draw();
          break;
      case GameConfig.STATES.PLAYING:
          if (now - this.lastUpdateTime >= GameConfig.GAME_SPEED) {
              this.update();
              this.lastUpdateTime = now;
          }
          this.drawGame();
          break;
      case GameConfig.STATES.PAUSED:
          this.drawGame();     // 先绘制游戏画面
          this.drawPaused();   // 再绘制暂停遮罩
          break;
      case GameConfig.STATES.GAME_OVER:
          this.drawGame();
          this.gameOver.draw(this.scorePanel.score);
          break;
  }

  requestAnimationFrame((t) => this.gameLoop(t));
}

/**
 * 获取游戏区域的实际尺寸
 * @returns {Object} 包含宽度和高度的对象
 */
getGameAreaDimensions() {
  const { GAME_AREA } = GameConfig.LAYOUT;
    
  return {
      width: Math.floor((this.canvas.width - GAME_AREA.PADDING * 2) / GameConfig.GRID_SIZE),
      height: Math.floor((this.canvas.height - GAME_AREA.TOP_MARGIN - GAME_AREA.PADDING) / GameConfig.GRID_SIZE),
      topMargin: GAME_AREA.TOP_MARGIN,
      padding: GAME_AREA.PADDING
  };
}

/**
 * 转换游戏坐标到画布坐标
 */
gameToCanvasPosition(gameX, gameY) {
  const { GAME_AREA } = GameConfig.LAYOUT;
  return {
      x: GAME_AREA.PADDING + gameX * GameConfig.GRID_SIZE,
      y: GAME_AREA.TOP_MARGIN + gameY * GameConfig.GRID_SIZE
  };
}

/**
* 检查位置是否在游戏区域内
* @param {Object} position - 包含 x 和 y 坐标的对象
* @returns {boolean} 是否在游戏区域内
*/
isWithinGameArea(position) {
  const dimensions = this.getGameAreaDimensions();
  return position.x >= 0 && 
         position.x < dimensions.width && 
         position.y >= 0 && 
         position.y < dimensions.height;
}
  /**
   * 开始游戏循环
   */
  start() {
      requestAnimationFrame((t) => this.gameLoop(t));
      SoundManager.loop('bgm');
  }
}